home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / faxd / FaxMachineInfo.c++ < prev    next >
C/C++ Source or Header  |  1994-08-01  |  11KB  |  471 lines

  1. /*    $Header: /usr/people/sam/fax/faxd/RCS/FaxMachineInfo.c++,v 1.29 1994/04/04 18:24:29 sam Rel $ */
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include <ctype.h>
  26. #include <osfcn.h>
  27. #include <unistd.h>
  28. #include <syslog.h>
  29. #include <sys/stat.h>
  30. #include <sys/file.h>
  31. #include <fcntl.h>
  32.  
  33. #include "config.h"
  34. #include "FaxMachineInfo.h"
  35. #include "FaxTrace.h"
  36. #include "class2.h"
  37.  
  38. static    fxBool getBoolean(const char* cp);
  39. static    fxBool getLine(FILE*, char* line, int cc, char*& tag, char*& val);
  40. static    int getNum(const char* s);
  41.  
  42. const fxStr FaxMachineCtlInfo::ctlDir(FAX_CTLDIR);
  43.  
  44. #define    isCmd(s,cmd)    (strcasecmp(s, cmd) == 0)
  45.  
  46. FaxMachineCtlInfo::FaxMachineCtlInfo()
  47. {
  48.     tracingLevel = -1;
  49. }
  50. FaxMachineCtlInfo::~FaxMachineCtlInfo() {}
  51.  
  52. void
  53. FaxMachineCtlInfo::restore(const fxStr& canon)
  54. {
  55.     mode_t omask = umask(022);
  56.     FILE* fp = fopen(ctlDir | "/" | canon, "r");
  57.     (void) umask(omask);
  58.     if (fp) {
  59.     char line[1024];
  60.     char* tag;
  61.     char* val;
  62.  
  63.     while (getLine(fp, line, sizeof (line), tag, val)) {
  64.         if (isCmd(tag, "rejectNotice")) {
  65.         rejectNotice = val;
  66.         } else if (isCmd(tag, "tracingLevel")) {
  67.         tracingLevel = getNum(val) & FAXTRACE_MASK;
  68.         }
  69.     }
  70.     fclose(fp);
  71.     }
  72. }
  73.  
  74. const fxStr&
  75. FaxMachineCtlInfo::getRejectNotice() const
  76. {
  77.     return rejectNotice;
  78. }
  79.  
  80. fxBool
  81. FaxMachineCtlInfo::getTracingLevel(int& l) const
  82. {
  83.     if (tracingLevel != -1) {
  84.     l = tracingLevel;
  85.     return (TRUE);
  86.     } else
  87.     return (FALSE);
  88. }
  89.  
  90. const fxStr FaxMachineInfo::infoDir(FAX_INFODIR);
  91.  
  92. FaxMachineInfo::FaxMachineInfo(const fxStr& number, fxBool)
  93. {
  94.     fp = NULL;
  95.     locked = 0;
  96.     supportsHighRes = TRUE;
  97.     supports2DEncoding = TRUE;
  98.     supportsPostScript = FALSE;
  99.     calledBefore = FALSE;
  100.     maxPageWidth = 2432;        // 1728 at 303 mm
  101.     maxPageLength = -1;            // unlimited
  102.     maxSignallingRate = BR_14400;    // T.17 14.4KB
  103.     minScanlineTime = ST_0MS;        // 0ms/0ms
  104.     changed = FALSE;
  105.     sendFailures = 0;
  106.     dialFailures = 0;
  107.  
  108.     fxStr canon(number);
  109.     for (int i = canon.length()-1; i >= 0; i--)
  110.     if (!isdigit(canon[i]))
  111.         canon.remove(i,1);
  112.  
  113.     FaxMachineCtlInfo::restore(canon);
  114.  
  115.     fxStr file(infoDir | "/" | canon);
  116.     mode_t omask = umask(022);
  117.     int fd = open((char*) file, O_RDWR|O_CREAT, 0644);
  118.     if (fd < 0)
  119.     syslog(LOG_ERR, "%s: open: %m", (char*) file);
  120.     (void) umask(omask);
  121.     if (fd >= 0) {
  122.     if (flock(fd, LOCK_EX|LOCK_NB) == 0 && (fp = fdopen(fd, "r+w")))
  123.         restore();
  124.     else
  125.         close(fd);
  126.     }
  127. }
  128. FaxMachineInfo::~FaxMachineInfo()
  129. {
  130.     if (fp) {
  131.     if (changed)
  132.         update();
  133.     fclose(fp);
  134.     }
  135. }
  136.  
  137. int
  138. FaxMachineInfo::operator==(const FaxMachineInfo& other) const
  139. {
  140.     return (
  141.     supportsHighRes == other.supportsHighRes
  142.      && supports2DEncoding == other.supports2DEncoding
  143.      && supportsPostScript == other.supportsPostScript
  144.      && calledBefore == other.calledBefore
  145.      && maxPageWidth == other.maxPageWidth
  146.      && maxPageLength == other.maxPageLength
  147.      && maxSignallingRate == other.maxSignallingRate
  148.      && minScanlineTime == other.minScanlineTime
  149.      && csi == other.csi
  150.      && jobInProgress == other.jobInProgress
  151.      && rejectNotice == other.rejectNotice
  152.      && sendFailures == other.sendFailures
  153.      && dialFailures == other.dialFailures
  154.      && lastSendFailure == other.lastSendFailure
  155.      && lastDialFailure == other.lastDialFailure
  156.     );
  157. }
  158.  
  159. int
  160. FaxMachineInfo::operator!=(const FaxMachineInfo& other) const
  161.     { return !(*this == other); }
  162.  
  163. const fxStr&
  164. FaxMachineInfo::getRejectNotice() const
  165. {
  166.     const fxStr& notice = FaxMachineCtlInfo::getRejectNotice();
  167.     if (notice == "")
  168.     return rejectNotice;
  169.     else
  170.     return notice;
  171. }
  172.  
  173. static fxBool
  174. getBoolean(const char* cp)
  175. {
  176.     return (strcasecmp(cp, "on") == 0 || strcasecmp(cp, "yes") == 0);
  177. }
  178.  
  179. static int
  180. getNum(const char* s)
  181. {
  182.     return ((int) strtol(s, NULL, 0));
  183. }
  184.  
  185. static fxBool
  186. getLine(FILE* fp, char* line, int n, char*& tag, char*& val)
  187. {
  188.     while (fgets(line, n-1, fp)) {
  189.     if (line[0] == '#')
  190.         continue;
  191.     char* cp = strchr(line, '\n');
  192.     if (cp)
  193.         *cp = '\0';
  194.     val = strchr(line, ':');
  195.     if (!val)
  196.         continue;
  197.     *val++ = '\0';
  198.     while (isspace(*val))
  199.         val++;
  200.     tag = line;
  201.     return (TRUE);
  202.     }
  203.     return (FALSE);
  204. }
  205.  
  206. #define    HIRES    0
  207. #define    G32D    1
  208. #define    PS    2
  209. #define    WD    3
  210. #define    LN    4
  211. #define    BR    5
  212. #define    ST    6
  213.  
  214. static const char* brnames[] =
  215.    { "2400", "4800", "7200", "9600", "12000", "14400" };
  216. #define    NBR    (sizeof (brnames) / sizeof (brnames[0]))
  217. static const char* stnames[] =
  218.    { "0ms", "5ms", "10ms/5ms", "10ms",
  219.      "20ms/10ms", "20ms", "40ms/20ms", "40ms" };
  220. #define    NST    (sizeof (stnames) / sizeof (stnames[0]))
  221.  
  222. void
  223. FaxMachineInfo::restore()
  224. {
  225.     char line[1024];
  226.     char* tag;
  227.     char* val;
  228.  
  229.     while (getLine(fp, line, sizeof (line), tag, val)) {
  230.     int b;
  231.     if (line[0] == '&') {            // locked down indicator
  232.         b = 1;
  233.         tag++;
  234.     } else
  235.         b = 0;
  236.     if (isCmd(tag, "supportsHighRes")) {
  237.         supportsHighRes = getBoolean(val);
  238.         locked |= (b<<HIRES);
  239.     } else if (isCmd(tag, "supports2DEncoding")) {
  240.         supports2DEncoding = getBoolean(val);
  241.         locked |= (b<<G32D);
  242.     } else if (isCmd(tag, "supportsPostScript")) {
  243.         supportsPostScript = getBoolean(val);
  244.         locked |= (b<<PS);
  245.     } else if (isCmd(tag, "calledBefore")) {
  246.         calledBefore = getBoolean(val);
  247.     } else if (isCmd(tag, "maxPageWidth")) {
  248.         maxPageWidth = atoi(val);
  249.         locked |= (b<<WD);
  250.     } else if (isCmd(tag, "maxPageLength")) {
  251.         maxPageLength = atoi(val);
  252.         locked |= (b<<LN);
  253.     } else if (isCmd(tag, "maxSignallingRate")) {
  254.         for (u_int i = 0; i < NBR; i++)
  255.         if (strcmp(brnames[i], val) == 0) {
  256.             maxSignallingRate = i;
  257.             locked |= (b<<BR);
  258.             break;
  259.         }
  260.     } else if (isCmd(tag, "minScanlineTime")) {
  261.         for (u_int i = 0; i < NST; i++)
  262.         if (strcmp(stnames[i], val) == 0) {
  263.             minScanlineTime = i;
  264.             locked |= (b<<ST);
  265.             break;
  266.         }
  267.     } else if (isCmd(tag, "remoteCSI")) {
  268.         csi = val;
  269.     } else if (isCmd(tag, "jobInProgress")) {
  270.         jobInProgress = val;
  271.     } else if (isCmd(tag, "rejectNotice")) {
  272.         rejectNotice = val;
  273.     } else if (isCmd(tag, "lastSendFailure")) {
  274.         lastSendFailure = val;
  275.     } else if (isCmd(tag, "lastDialFailure")) {
  276.         lastDialFailure = val;
  277.     } else if (isCmd(tag, "sendFailures")) {
  278.         sendFailures = atoi(val);
  279.     } else if (isCmd(tag, "dialFailures")) {
  280.         dialFailures = atoi(val);
  281.     }
  282.     }
  283.     changed = FALSE;
  284. }
  285.  
  286. #define    isLocked(b)    (locked & (1<<b))
  287.  
  288. void
  289. FaxMachineInfo::setSupportsHighRes(fxBool b)
  290. {
  291.     if (!isLocked(HIRES)) {
  292.      supportsHighRes = b;
  293.      changed = TRUE;
  294.     }
  295. }
  296.  
  297. void
  298. FaxMachineInfo::setSupports2DEncoding(fxBool b)
  299. {
  300.     if (!isLocked(G32D)) {
  301.     supports2DEncoding = b;
  302.     changed = TRUE;
  303.     }
  304. }
  305.  
  306. void
  307. FaxMachineInfo::setSupportsPostScript(fxBool b)
  308. {
  309.     if (!isLocked(PS)) {
  310.     supportsPostScript = b;
  311.     changed = TRUE;
  312.     }
  313. }
  314.  
  315. void
  316. FaxMachineInfo::setCalledBefore(fxBool b)
  317. {
  318.     calledBefore = b;
  319.     changed = TRUE;
  320. }
  321.  
  322. void
  323. FaxMachineInfo::setMaxPageWidth(int v)
  324. {
  325.     if (!isLocked(WD)) {
  326.     maxPageWidth = v;
  327.     changed = TRUE;
  328.     }
  329. }
  330.  
  331. void
  332. FaxMachineInfo::setMaxPageLength(int v)
  333. {
  334.     if (!isLocked(LN)) {
  335.     maxPageLength = v;
  336.     changed = TRUE;
  337.     }
  338. }
  339.  
  340. void
  341. FaxMachineInfo::setMaxSignallingRate(int v)
  342. {
  343.     if (!isLocked(BR)) {
  344.     maxSignallingRate = v;
  345.     changed = TRUE;
  346.     }
  347. }
  348.  
  349. void
  350. FaxMachineInfo::setMinScanlineTime(int v)
  351. {
  352.     if (!isLocked(ST)) {
  353.     minScanlineTime = v;
  354.     changed = TRUE;
  355.     }
  356. }
  357.  
  358. void
  359. FaxMachineInfo::setCSI(const fxStr& v)
  360. {
  361.     if (csi != v) {
  362.     csi = v;
  363.     changed = TRUE;
  364.     }
  365. }
  366.  
  367. void
  368. FaxMachineInfo::setJobInProgress(const fxStr& v)
  369. {
  370.     if (jobInProgress != v) {
  371.     jobInProgress = v;
  372.     changed = TRUE;
  373.     }
  374. }
  375.  
  376. void
  377. FaxMachineInfo::setRejectNotice(const fxStr& v)
  378. {
  379.     if (rejectNotice != v) {
  380.     rejectNotice = v;
  381.     changed = TRUE;
  382.     }
  383. }
  384.  
  385. void
  386. FaxMachineInfo::setLastSendFailure(const fxStr& v)
  387. {
  388.     if (lastSendFailure != v) {
  389.     lastSendFailure = v;
  390.     changed = TRUE;
  391.     }
  392. }
  393.  
  394. void
  395. FaxMachineInfo::setLastDialFailure(const fxStr& v)
  396. {
  397.     if (lastDialFailure != v) {
  398.     lastDialFailure = v;
  399.     changed = TRUE;
  400.     }
  401. }
  402.  
  403. void
  404. FaxMachineInfo::setSendFailures(int v)
  405. {
  406.     if (sendFailures != v) {
  407.     sendFailures = v;
  408.     changed = TRUE;
  409.     }
  410. }
  411.  
  412. void
  413. FaxMachineInfo::setDialFailures(int v)
  414. {
  415.     if (dialFailures != v) {
  416.     dialFailures = v;
  417.     changed = TRUE;
  418.     }
  419. }
  420.  
  421. static void
  422. putBoolean(FILE* fp, const char* tag, fxBool locked, fxBool b)
  423. {
  424.     fprintf(fp, "%s%s: %s\n", locked ? "&" : "", tag, b ? "yes" : "no");
  425. }
  426.  
  427. static void
  428. putDecimal(FILE* fp, const char* tag, fxBool locked, int v)
  429. {
  430.     fprintf(fp, "%s%s: %d\n", locked ? "&" : "", tag, v);
  431. }
  432.  
  433. static void
  434. putString(FILE* fp, const char* tag, fxBool locked, const char* v)
  435. {
  436.     fprintf(fp, "%s%s: %s\n", locked ? "&" : "", tag, v);
  437. }
  438.  
  439. static void
  440. putIfString(FILE* fp, const char* tag, fxBool locked, const char* v)
  441. {
  442.     if (*v != '\0')
  443.     fprintf(fp, "%s%s: %s\n", locked ? "&" : "", tag, v);
  444. }
  445.  
  446. void
  447. FaxMachineInfo::update()
  448. {
  449.     rewind(fp);
  450.     putBoolean(fp, "supportsHighRes", isLocked(HIRES), supportsHighRes);
  451.     putBoolean(fp, "supports2DEncoding", isLocked(G32D),supports2DEncoding);
  452.     putBoolean(fp, "supportsPostScript", isLocked(PS), supportsPostScript);
  453.     putBoolean(fp, "calledBefore", FALSE, calledBefore);
  454.     putDecimal(fp, "maxPageWidth", isLocked(WD), maxPageWidth);
  455.     putDecimal(fp, "maxPageLength", isLocked(LN), maxPageLength);
  456.     putString(fp, "maxSignallingRate", isLocked(BR),
  457.     brnames[fxmin(maxSignallingRate, BR_14400)]);
  458.     putString(fp, "minScanlineTime", isLocked(ST),
  459.     stnames[fxmin(minScanlineTime, ST_40MS)]);
  460.     putString(fp, "remoteCSI", FALSE, csi);
  461.     putIfString(fp, "jobInProgress", FALSE, jobInProgress);
  462.     putIfString(fp, "rejectNotice", FALSE, rejectNotice);
  463.     putDecimal(fp, "sendFailures", FALSE, sendFailures);
  464.     putIfString(fp, "lastSendFailure", FALSE, lastSendFailure);
  465.     putDecimal(fp, "dialFailures", FALSE, dialFailures);
  466.     putIfString(fp, "lastDialFailure", FALSE, lastDialFailure);
  467.     fflush(fp);
  468.     (void) ftruncate(fileno(fp), ftell(fp));        // XXX
  469.     changed = FALSE;
  470. }
  471.